package users

import (
	"context"
	"errors"
	"github.com/golang-jwt/jwt/v5"
	"product/common/datetime"
	"product/common/jwts"
	"product/common/validator"
	"time"

	"product/authorization/serve/internal/svc"
	"product/authorization/serve/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type RefreshTokenLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// NewRefreshTokenLogic refresh token
func NewRefreshTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RefreshTokenLogic {
	return &RefreshTokenLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *RefreshTokenLogic) RefreshToken(req *types.RefreshTokenReq) (resp *types.RefreshTokenResp, err error) {
	ok, err := validTokenInput(req)
	if !ok && err != nil {
		return &types.RefreshTokenResp{
			Token:   "",
			ExpDate: "",
		}, nil
	}
	// 解析token
	token, err := jwts.ParseToken(req.Token, l.svcCtx.Config.JwtConf.Secret)
	if err != nil {
		return &types.RefreshTokenResp{
			Token:   "",
			ExpDate: "",
		}, nil
	}

	expDate := datetime.AddHours(time.Now(), l.svcCtx.Config.JwtConf.Expires)
	refreshClaims := &jwts.JwtHollyClaims{
		ID:   token.ID,
		Name: token.Name,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(expDate),
			IssuedAt:  jwt.NewNumericDate(time.Now()),
			Issuer:    l.svcCtx.Config.JwtConf.Issuer,
			Audience:  jwt.ClaimStrings{l.svcCtx.Config.JwtConf.Audience},
			Subject:   "Token",
		},
	}
	refreshToken, err := jwts.GenToken(refreshClaims, l.svcCtx.Config.JwtConf.Secret)
	if err != nil || validator.IsEmptyString(refreshToken) {
		return &types.RefreshTokenResp{
			Token:   "",
			ExpDate: "",
		}, nil
	}
	return &types.RefreshTokenResp{
		Token:   refreshToken,
		ExpDate: datetime.FormatDateTime(expDate),
	}, nil
}

func validTokenInput(req *types.RefreshTokenReq) (bool, error) {
	if validator.IsEmptyString(req.Token) {
		return false, errors.New("token不能为空")
	}
	return true, nil
}
